package com.example.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

/**
 * This class performs some basic, mundane tasks that will be used throughout this project.
 * 
 * The class contains exclusively static variables and functions.
 * 
 * It is not meant to be instantiated or extended.
 * @author Jacob
 *
 */
public final class BasicFunctions {
	
	/**
	 * 
	 * This is a helper function that generates the Http POST request body in byte array format
	 * from two arrays of strings, one being a list of keys and the other being a list of values.
	 * 
	 * The indices in the key array correspond to the mapped value in the map array.
	 * 
	 * @param keyArray An array of keys. The position of an element in the array corresponds
	 * to the same index in the array of values.
	 * @param valueArray An array of values.
	 * @return Http POST request body in byte array, or null if the two arrays differ in length.
	 */
	public static byte[] convertParamMapToBytes(String[] keyArray, String[] valueArray) {
		HashMap<String, String> paramMap = makeParamMap(keyArray, valueArray);
		if (paramMap == null) {
			return null;
		}
		return convertParamMapToBytes(paramMap);
	}
	
	/**
	 * Given a mapping of keys and values, convert such a mapping into a byte array.
	 * This byte array is the body of an HTTP post request, with the array formatted to
	 * such a request's standard.
	 * @param paramMap A mapping of keys to values.
	 * @return The HTTP post request body in byte array.
	 */
	public static byte[] convertParamMapToBytes(HashMap<String, String> paramMap) {
	    StringBuffer data = new StringBuffer();
	    Iterator<Entry<String, String>> paramIterator = paramMap.entrySet().iterator();
	    while (paramIterator.hasNext()) {
	        Entry<String, String> param = paramIterator.next();
	        data.append(param.getKey());
	        data.append("=");
	        data.append(param.getValue());
	        if (paramIterator.hasNext()) {
	            data.append('&');
	        }
	    }
	    byte[] bytesArray = data.toString().getBytes();
	    return bytesArray;
	}
	
	/**
	 * Generates a mapping of keys to values, which will be making up the body of a Http Post request
	 * method in JSON format from two arrays of Strings. Specifically:
	 * 
	 * Key1=Value1
	 * Key2=Value2...
	 * 
	 * Example function call:
	 * 
	 * String[] keyList =  ["Age", "Gender", "FavoriteFood"];
	 * String[] valueList = ["20", "Male", "Apple"];
	 * HashMap<String, String> paramMap= makeParamMap(keyList, valueList);
	 * 
	 * The resulting map (In no particular order):
	 * 
	 * {
	 * Age = 20,
	 * Gender = Male,
	 * FavoriteFood = Apple
	 * }
	 * 
	 * The two arrays of String must have equal length, or a null map will be returned.
	 * 
	 * @param keyArray An array of keys. The position of an element in the array corresponds
	 * to the same index in the array of values.
	 * @param valueArray An array of values.
	 * @return A map of key : value, or null if the two arrays differ in length.
	 */
	public static HashMap<String, String> makeParamMap(String[] keyArray, String[] valueArray) {
		if (keyArray.length != valueArray.length) {
			return null; //The number of keys must match the number of values.
		}
		HashMap<String, String> paramMap = new HashMap<String, String>();	
		return paramMap;
	}

	/**
	 * Helper function for reading an HTTP response from the server. 
	 * @param in The input stream of the HTTP Url connection.
	 * @return A long string containing the response's body only.
	 * @throws IOException If there is an error reading the response.
	 */
	public static String inputStreamToString(InputStream in) throws IOException {
		StringBuffer data = new StringBuffer();
		String line = "";
		BufferedReader reader = new BufferedReader(new InputStreamReader(in));
		line = reader.readLine();
		while (line != null) {
			data.append(line);
			line = reader.readLine();
		}
		return reader.toString();
	}
	
}
